package com.tanhua.server.service;

import com.tanhua.commons.constant.Constants;
import com.tanhua.dubbo.api.db.*;
import com.tanhua.model.db.*;
import com.tanhua.model.vo.*;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class TestSoulService {

    @DubboReference
    private TestQuestionApi testQuestionApi;

    @DubboReference
    private TestDimensionApi testDimensionApi;

    @DubboReference
    private TestOptionApi testOptionApi;

    @DubboReference
    private UserReportApi userReportApi;

    @DubboReference
    private DimensionApi dimensionApi;

    @DubboReference
    private PersonalityTypeApi personalityTypeApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionnaireApi questionnaireApi;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @DubboReference
    private QuestionnaireLevelApi questionnaireLevelApi;


    /**
     * 灵魂测试提交问卷
     *
     * @param param
     */
    public String testSoul(Map<String, List<AnswersVo>> param) {
        Long userId = UserHolder.getUserId();
        List<Long> waixiang = new ArrayList<>();//外向纬度值
        List<Long> panduan = new ArrayList<>();//判断纬度值
        List<Long> chouxiang = new ArrayList<>();//抽象纬度值
        List<Long> lixing = new ArrayList<>();//理性
        UserReport userReport = new UserReport();
        //问卷id
        Long questionnaireId = null;
        Collection<List<AnswersVo>> values = param.values();
        Iterator<List<AnswersVo>> listIterator = values.iterator();
        while (listIterator.hasNext()) {
            List<AnswersVo> answersVos = listIterator.next();

            for (AnswersVo answersVo : answersVos) {
                Integer questionId = Integer.parseInt(answersVo.getQuestionId());
                Integer optionId = Integer.parseInt(answersVo.getOptionId());
                QuestionTest questionTest = testQuestionApi.findById(questionId);
                if (questionTest != null) {

                    //问卷ID赋值
                    questionnaireId = (long) questionTest.getQuestionnaireId();

                    //3.根据question获取维度id
                    Integer dimensionById = questionTest.getDimensionId();
                    //4.根据维度id查询在对应的维度名称
                    String dimensionName = testDimensionApi.findDimensionId(dimensionById);
                    if (null != dimensionName) {
                        if (dimensionName.equals(Constants.QUESTION_TYPE_WAIXIANG)) {
                            waixiang.add(optionId.longValue());

                        }
                        if (dimensionName.equals(Constants.QUESTION_TYPE_CHOUXIANG)) {
                            chouxiang.add(optionId.longValue());
                            continue;
                        }
                        if (dimensionName.equals(Constants.QUESTION_TYPE_LIXING)) {
                            lixing.add(optionId.longValue());
                            continue;
                        }
                        if (dimensionName.equals(Constants.QUESTION_TYPE_PANDUAN)) {
                            panduan.add(optionId.longValue());
                        }
                    }
                }
            }
        }

        //7.查询各维度总分
        Integer waiXiangSum = testOptionApi.findByIds(waixiang);
        Integer panDuangSum = testOptionApi.findByIds(panduan);
        Integer liXingSum = testOptionApi.findByIds(lixing);
        Integer chouXiangSum = testOptionApi.findByIds(chouxiang);
        log.debug("各个维度的分数为：waiXiangSum：{}，panDuangSum：{}，liXingSum：{}，chouXiangSum：{}", waiXiangSum, panDuangSum,
                liXingSum, chouXiangSum);
        //8.为userReport设置各参数
        //最大的维度
        userReport.setMaxValue(scoreDouble(waiXiangSum, panDuangSum, liXingSum, chouXiangSum));
        //各维度百分比
        userReport.setWaixiang(getPercentage(waiXiangSum, waixiang.size()));
        userReport.setLixing(getPercentage(liXingSum, lixing.size()));
        userReport.setChouxiang(getPercentage(chouXiangSum, chouxiang.size()));
        userReport.setPanduan(getPercentage(panDuangSum, panduan.size()));

        userReport.setQuestionnaireId(questionnaireId);
        userReport.setCreated(new Date());
        userReport.setUserId(userId);
        //报告ID
        String id = userReportApi.insertOrUpdate(userReport).toString();

        String key = Constants.USER_QUESTIONNAIRE + userId;
        String hashKey = Constants.QUESTIONNAIRE_ID + questionnaireId;
        redisTemplate.opsForHash().put(key, hashKey, id);
        //9.返回id
        return id;
    }

    /**
     * 四个维度最大值,判断类型
     *
     * @param num1
     * @param num2
     * @param num3
     * @param num4
     * @return
     */
    public String scoreDouble(Integer num1, Integer num2, Integer num3, Integer num4) {
        int c = num1 + num2 + num3 + num4;
        //1.小于21.猫头鹰
        if (c <= 21) {
            return Constants.QUESTION_TYPE_WAIXIANG;
            //2.21分-40分:白兔型
        } else if (c > 21 && c <= 40) {
            return Constants.QUESTION_TYPE_PANDUAN;
            //41分-55分:狐狸型
        } else if (c > 41 && c <= 55) {
            return Constants.QUESTION_TYPE_CHOUXIANG;
            //56以上：狮子型
        } else {
            return Constants.QUESTION_TYPE_LIXING;
        }
    }

    /**
     * 计算用户在当前维度的占比
     *
     * @param total
     * @param listSize
     * @return
     */
    public String getPercentage(Integer total, int listSize) {
        BigDecimal bigDecimal = new BigDecimal(total / listSize);
        double doubleValue = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        if (doubleValue <= 1.5)
            return "70%";
        else if (doubleValue > 1.5 && doubleValue <= 2)
            return "80%";
        else if (doubleValue > 2 && doubleValue <= 4)
            return "90%";
        else if (doubleValue > 4 && doubleValue < 6)
            return "95%";
        else
            return "100%";
    }


    /**
     * 查看我的报告
     *
     * @param id
     * @return
     */
    public UserReportVo getMyReport(Long id) {
        //返回的vo
        UserReportVo userReportVo = new UserReportVo();

        //用户报告
        UserReport userReport = userReportApi.findPersonalReport(id);
        if (null == userReport)
            return userReportVo;
        String maxValue = userReport.getMaxValue();
        //维度
        Dimension dimension = dimensionApi.findTypeByName(maxValue);
        //维度对应的性格
        PersonalityType personalityType = personalityTypeApi.findById(dimension.getId());
        //各维度集合list
        List<Map<String, String>> list = new ArrayList<>();

        Map<String, String> waixiang = new HashMap<>();
        waixiang.put("key", "外向");
        waixiang.put("value", userReport.getWaixiang());

        Map<String, String> panduan = new HashMap<>();
        panduan.put("key", "判断");
        panduan.put("value", userReport.getPanduan());

        Map<String, String> chouxiang = new HashMap<>();
        chouxiang.put("key", "抽象");
        chouxiang.put("value", userReport.getChouxiang());

        Map<String, String> lixing = new HashMap<>();
        lixing.put("key", "理性");
        lixing.put("value", userReport.getLixing());
        //添加到维度集合
        Collections.addAll(list, waixiang, panduan, chouxiang, lixing);

        BeanUtils.copyProperties(personalityType, userReportVo);
        userReportVo.setDimensions(list);
        //和我相似的用户id集合
        List<Long> userIds = userReportApi.findSimilarUserIdByMaxValue(maxValue,userReport.getQuestionnaireId());

        //移出自己
        if (userIds.contains(UserHolder.getUserId()))
            userIds.remove(UserHolder.getUserId());

        //相似用户
        List<UserInfo> userInfoList = null;
        if (!CollectionUtils.isEmpty(userIds))
            userInfoList = userInfoApi.findByBatchIds(userIds);

        userReportVo.setSimilarYou(userInfoList);
        return userReportVo;
    }


    /**
     * 问卷查询
     *
     * @return
     */
    public List<QuestionnaireVo> questionnaireList() {
        List<QuestionnaireVo> returnList = new ArrayList<>();
        String report1 = null;
        String report2 = null;
        List<Questionnaire> questionnaireList = questionnaireApi.findAll();
        for (Questionnaire questionnaire : questionnaireList) {
            //问卷对象vo
            QuestionnaireVo questionnaireVo = new QuestionnaireVo();
            //问卷id
            Integer questionnaireId = questionnaire.getId();

            questionnaireVo.setId(questionnaireId.toString());
            questionnaireVo.setCover(questionnaire.getCover());
            questionnaireVo.setStar(questionnaire.getStar());
            questionnaireVo.setName(questionnaire.getName());
            //问卷等级id
            Integer levelId = questionnaire.getLevel();
            QuestionnaireLevel questionnaireLevel = questionnaireLevelApi.findById(levelId);
            questionnaireVo.setLevel(questionnaireLevel.getName());


            //问题vo
            List<QuestionVo> questionVos = new ArrayList<>();
            //题目集合
            List<QuestionTest> questionList = testQuestionApi.findByQuestionnaireId(questionnaireId);
            for (QuestionTest question : questionList) {
                QuestionVo questionVo = new QuestionVo();
                Integer questionId = question.getId();
                questionVo.setId(questionId.toString());
                questionVo.setQuestion(question.getName());
                //选项vo
                List<OptionVo> optionVos = new ArrayList<>();
                List<Option> optionList = testOptionApi.findByQuestionId(questionId);
                for (Option option : optionList) {
                    OptionVo optionVo = new OptionVo();
                    optionVo.setId(option.getId().toString());
                    optionVo.setOption(option.getName());
                    optionVos.add(optionVo);
                }
                questionVo.setOptions(optionVos);
                questionVos.add(questionVo);
            }
            questionnaireVo.setQuestions(questionVos);

            //从redis里查用户对这份问卷是否回答过
            String key = Constants.USER_QUESTIONNAIRE + UserHolder.getUserId();
            String hashKey = Constants.QUESTIONNAIRE_ID + questionnaireId;
            String reportId = (String) redisTemplate.opsForHash().get(key, hashKey);
            //回答过就把相应的信息设置到vo里面
            if (1 == questionnaireId) {
                //如果是第一份问卷，则不上锁
                questionnaireVo.setIsLock(0);//是否锁住（0解锁，1锁住）
                if (null != reportId) {
                    questionnaireVo.setReportId(reportId);//报告ID
                    report1 = reportId;
                }
            }
            //如果第一份试卷报告不为空，那么给第二份试卷解锁
            if (null != report1) {
                if (2 == questionnaireId) {
                    questionnaireVo.setIsLock(0);//是否锁住（0解锁，1锁住）
                    questionnaireVo.setReportId(reportId);//报告ID
                    report2 = reportId;
                }
            }
            if (null != report2) {
                if (3 == questionnaireId) {
                    questionnaireVo.setIsLock(0);//是否锁住（0解锁，1锁住）
                    questionnaireVo.setReportId(reportId);//报告ID
                }
            }
            returnList.add(questionnaireVo);
        }
        return returnList;
    }
}
